package com.bitoon.basketdudes.web.admin;

import com.bitoon.basketdudes.web.*;
import com.bitoon.basketdudes.web.datos.EstadisticaEquipo;
import com.bitoon.basketdudes.web.jpa.*;
import com.bitoon.web.utils.LocalizedText;
import org.apache.log4j.Logger;
import java.util.*;
import javax.persistence.*;

public class DetalleEquipoAdmin extends DetalleEquipo {

    private Logger log = Logger.getLogger(DetalleEquipoAdmin.class);
    private int id;
    //para la modificacion de: nombre, nick y nombre_url del equipo
    private boolean estado;
    private boolean modificar;
    private boolean error;
    private String url;
    private String nombre_equipo;
    private String nick_equipo;

    //acceso a la clase estatica BaseActionAdmin
    protected BaseActionAdmin bsaadmin = BaseActionAdmin.getInstance();

    @Override
    public String execute() {

        String retorno = SUCCESS;

        log.debug("[DetalleEquipoAdmin] urlEquipo: " + getUrlEquipo());

        if(id!=0l){
            if(getModificar()==false){
                //colsultamos los datos del equipo
                retorno = mostrarInfoEquipo(id);
            }else{
                //modificamos la informacion del equipo
                retorno = modificarInfoEquipo(id);
             }
        }
        return retorno;
    }

        public List<ArmarioEquipo> getArmarioEquipo(int idEquipo) {
        EntityManager em = null;
        List<ArmarioEquipo> listaArmarios = null;

        try {
            em = bsaadmin.getEmfAdmin().createEntityManager(); // checked

            Query q  = em.createNamedQuery("ArmarioEquipo.findByEquipoId");
            q.setParameter("equipoId", idEquipo);
            listaArmarios = (List<ArmarioEquipo>)q.getResultList();

            if(listaArmarios.isEmpty()){
                listaArmarios = null;
            }

        } catch (NoResultException e) {
            log.debug("[getArmarioEquipo][armario del equipo " + idEquipo + " no encontrado]");
        } catch (Exception e) {
            log.error("[getArmarioEquipo]: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return listaArmarios;
    }

    public String getTextoObjeto(String tipo, String key) {

        String retorno = "xx-xx";

        try{
            if (tipo.equals("tipo")) {
                retorno = LocalizedText.getInstance().getTipoObjeto(getIdioma(), key);
            } else if (tipo.equals("nombre")) {
                retorno = LocalizedText.getInstance().getNombreObjeto(getIdioma(), key);
            } else if (tipo.equals("descripcion")) {
                retorno = LocalizedText.getInstance().getDescripcionObjeto(getIdioma(), key);
            } else if (tipo.equals("caracteristica")) {
                retorno = LocalizedText.getInstance().getNombreCaracteristica(getIdioma(), key);
            }
        }catch(Exception e){ log.debug("[getTextoObjeto] Error:" + e); }

        return retorno;

    }

    public List<DatoTipoCarta> getCartasEquipo(int idEquipo) {
        EntityManager em = null;
        List<DatoTipoCarta> listaCartas = null;

        try {
            em = bsaadmin.getEmfAdmin().createEntityManager(); // checked

            log.debug("[getCartasEquipo] Equipo_id: "+idEquipo);

            Query q  = em.createNativeQuery("SELECT row_number() over(order by m.nombre) as indice,m.id as rutaImagen,m.nombre as cadena,c.categoria_id-510 as nivel,sum(ce.cantidad) as cantidad FROM basket.carta_equipo ce join basket.carta c on (ce.carta_id=c.id) join basket.m_carta m on (c.m_carta_id=m.id) WHERE ce.equipo_id= " + idEquipo + " GROUP BY m.id,m.nombre,nivel,c.categoria_id order by m.nombre",DatoTipoCarta.class);

            listaCartas = (List<DatoTipoCarta>)q.getResultList();

            if(listaCartas.isEmpty()){
                listaCartas = null;
            }

        } catch (NoResultException e) {
            log.debug("[getCartasEquipo][armario del equipo " + idEquipo + " no encontrado]");
        } catch (Exception e) {
            log.error("[getCartasEquipo]: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return listaCartas;
    }

    public List<Partido> resultadosPartidosAdmin() {

        EntityManager em = null;
        Equipo equipo = null;

        try {
            em = bsaadmin.getEmfAdmin().createEntityManager(); // checked

            //ahora buscamos el equipo por id,no por url
            Query q  = em.createNamedQuery("Equipo.findById");
            q.setParameter("idEquipo", id);

            equipo = (Equipo)q.getSingleResult();

            if (equipo != null) {
                setEquipoMostrar(equipo);
                // fijar datos con los resultados de la query
                setDatos(getPartidosIdEquipoAdmin(equipo.getId()));
            }
        } catch (Exception e) {
            log.error("Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return getDatos();
    }

    public String modificarInfoEquipo(int id){
        EntityManager em = null;
        Equipo equipo = null;
        String retorno = "mod_ok";

        log.debug("Modifico: " +modificar);

        try {
            em = bsaadmin.getEmfAdmin().createEntityManager(); // checked

            Query q  = em.createNamedQuery("Equipo.findById");
            q.setParameter("idEquipo", id);

            equipo = (Equipo)q.getSingleResult();

            if (equipo != null) {
                if(validarDatosEquipo()){
                    //actualizamos su nombre y nick
                    em.getTransaction().begin();

                    log.debug("[modificarInfoEquipo] Realizo el UPDATE");

                    q = em.createNativeQuery("update basket.equipo set nick= :nick,nombre= :nombre,nombre_url = :nombreUrl where id= :id");
                    log.debug("update basket.equipo set nick='"+ getNick_equipo()+ "',nombre='" + getNombre_equipo() + "'" + " where id=" + equipo.getId());
                    q.setParameter("id",equipo.getId());
                    q.setParameter("nombre", getNombre_equipo());
                    q.setParameter("nick", getNick_equipo());
                    q.setParameter("nombreUrl",getNombre_equipo().toLowerCase()+"-"+getNick_equipo().toLowerCase());

                    q.executeUpdate();

                    em.getTransaction().commit();

                    setError(false);
                    setModificar(false);

                    setUrlEquipo(getNombre_equipo().toLowerCase() + "-" +getNick_equipo().toLowerCase());

                    log.debug("[modificarManager] nuevo equipo: " + getUrlEquipo());
                    setEquipoMostrar(buscarEquipo(getUrlEquipo(), em));
                    setEstEquipo(buscarEstEquipo(getEquipoMostrar().getId(), em));
                    EstadisticaEquipo estadistica = new EstadisticaEquipo();
                    estadistica.calculaMedia(equipo.getPlantilla());
                    setEstadisticaEquipo(estadistica);
                }else{
                    log.debug("[modificarManager] ERROR, modificacion de nombre equipo no valido");
                    setError(true);
                    setModificar(true);
                    retorno = "mod_error";
                }
            }
        } catch (Exception e) {
            log.error("Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }

        return retorno;
    }
    
    protected Equipo buscarEquipo(String nombreUrl, EntityManager em) {
        Equipo equipo = null;

        try {
            Query q = em.createNamedQuery("Equipo.findByNombreUrl");
            q.setParameter("nombre", nombreUrl);

            equipo = (Equipo)q.getSingleResult();

        } catch (Exception e) {
            log.error("[getEquipo]: " + e);
        }

        return equipo;
    }

    private EstEquipo buscarEstEquipo(int equipoId, EntityManager em) {
        EstEquipo estEquipo = null;

        try {
            Query q = em.createNamedQuery("EstEquipo.findByEquipoId");
            q.setParameter("equipoId", equipoId);

            estEquipo = (EstEquipo)q.getSingleResult();

            log.debug("estEquipo: " + estEquipo);
        } catch (Exception e) {
            log.error("[getEquipo]: " + e);
        }

        return estEquipo;
    }


    private boolean validarDatosEquipo(){
        //comprobamos que el nombre y el nick del equipo son válidos

        Boolean existe = true; // por defecto los datos son validos
        EntityManager em = null;
        Equipo equipo =null;

        log.info("[validarDatosEquipo] validando equipo.");

        //comprobar si cumple el formato el nombre y nick nuevos
        if(validarFormato()==true){
            try {
                em = bsaadmin.getEmfAdmin().createEntityManager();

                log.info("[validarDatosEquipo] formato equipo OK!.");

                // Comprobar si el nombre nuevo existe entre los equipos existentes
                Query q = em.createNamedQuery("Equipo.findByNombreYNick");
                q.setParameter("nombre", getNombre_equipo().toLowerCase());
                q.setParameter("nick", getNick_equipo().toLowerCase());

                try{
                    equipo = (Equipo)q.getSingleResult();
                }catch(Exception e){}

                //si existe devolvemos false = COMBINACION de NOMBRE/NICK YA EXISTE
                if ( equipo!=null ) {
                    log.debug("[validarDatosEquipo] Nombre/nick no se pueden usar,existe ya.");
                    existe = false;
                }
            } catch (Exception e) {
                log.error("Error", e);
            } finally {
                try { em.close(); } catch (Exception e) { }
            }
        }else{
            existe = false; //formato no valido
        }

        return existe;
    }

    private boolean validarFormato(){
        boolean valido = true; //por defecto formato valido

        //comprobar si cumple el formato el nombre
        if(getNombre_equipo().length()<=10 && getNick_equipo().length()<=10){
            int i=0;
            char _key;
            //mientras sea un caracter valido y no elsten todos validados
            log.debug("[nombre] " + getNombre_equipo());
            while(i<getNombre_equipo().length() && valido==true){
                _key = getNombre_equipo().charAt(i);
                if ((_key >= 'a' && _key <= 'z') || (_key >= 'A' && _key <= 'Z') || _key == '&' || (_key >= '0' && _key <= '9')) {
                    valido = true;
                }else{
                    valido = false;
                    log.debug("[validarDatosEquipo] Nombre no cumple formato.");
                }
                ++i;
            }

            i=0;
            log.debug("[nick] " + getNick_equipo());
            while(i<getNick_equipo().length() && valido==true){
                _key = getNick_equipo().charAt(i);
                if ((_key >= 'a' && _key <= 'z') || (_key >= 'A' && _key <= 'Z') || _key == '&' || (_key >= '0' && _key <= '9')) {
                    valido = true;
                }else{
                    valido = false;
                    log.debug("[validarDatosEquipo] Nick no cumple formato.");
                }
                ++i;
            }
        }

        return valido;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    public boolean getModificar() {
        return modificar;
    }

    public void setModificar(boolean modificar) {
        this.modificar = modificar;
    }

    public boolean getError() {
        return error;
    }

    public void setError(boolean error) {
        this.error = error;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public boolean isEstado() {
        return estado;
    }

    public void setEstado(boolean estado) {
        this.estado = estado;
    }

    public String getNombre_equipo() {
        return nombre_equipo;
    }

    public void setNombre_equipo(String nombre_equipo) {
        this.nombre_equipo = nombre_equipo;
    }

    public String getNick_equipo() {
        return nick_equipo;
    }

    public void setNick_equipo(String nick_equipo) {
        this.nick_equipo = nick_equipo;
    }

    public BaseActionAdmin getBsaadmin() {
        return bsaadmin;
    }

    public void setBsaadmin(BaseActionAdmin bsaadmin) {
        this.bsaadmin = bsaadmin;
    }
}
